package com.azier.generator;

import com.azier.kapacitor.util.CollectionUtil;
import com.azier.kapacitor.util.JsonUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import freemarker.template.Configuration;
import freemarker.template.Template;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 1 * @Author: luoj
 * 2 * @Date: 2019/11/11 17:25
 * 3
 */
public class Generator {
    private static final Map<String,Method> methodMap = new HashMap<>();
    private static final Map<String,Node> nodeMap = new HashMap<>();

    public static void main(String[] args) {

        //            JSON转Map
        try {
            String nodeMapFile = FreeMarkUtil.class.getResource("").getPath() + "nodeMap.json";
            String methodMapFile = FreeMarkUtil.class.getResource("").getPath() + "methodMap.json";
            String nodeMapJson = readFile(new File(nodeMapFile));
            String methodMapJson = readFile(new File(methodMapFile));
//            ObjectMapper mapper = JsonUtil.newMapper();
//            mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, false);
//            mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, false);
//            HashMap<String,Node> nodeMap = mapper.readValue(nodeMapJson, new TypeReference<HashMap<String, Node>>() {});
//            HashMap<String,Node> methodMap = mapper.readValue(methodMapJson, new TypeReference<HashMap<String, Node>>() {});
            HashMap<String,Node> nodeMap = JsonUtil.fromJson(nodeMapJson, new TypeReference<HashMap<String, Node>>() {});
            HashMap<String,Method> methodMap = JsonUtil.fromJson(methodMapJson, new TypeReference<HashMap<String, Method>>() {});
            //先生成method
            for (Map.Entry<String, Method> methodEntry : methodMap.entrySet()) {
                format(methodEntry.getValue(),"D:"+File.separator+"code" +File.separator+ "method" +File.separator+methodEntry.getKey()+".java","D:"+File.separator+"IdeaProjects"+File.separator+"kapacitor-java"+File.separator+"src"+File.separator+"main"+File.separator+"java"+File.separator+"com"+File.separator+"azier"+File.separator+"generator"+File.separator+"templ"+File.separator+"method.ftl");
            }
            //再拼凑Node
            for (Map.Entry<String, Node> nodeEntry : nodeMap.entrySet()) {
                Node node = nodeEntry.getValue();
                List<Node> nodes = new ArrayList<>();
                node.setNodes(nodes);
                List<String> notFound = new ArrayList<>();
                node.setNotFound(notFound);
                if (CollectionUtil.isNotEmpty(node.getLinkNodes())) {
                    for (String linkNode : node.getLinkNodes()) {
                        Node nodeL = nodeMap.get(linkNode);
                        if(nodeL==null){
                            notFound.add(linkNode);
                        }else {
                            nodes.add(nodeL);
                        }
                    }
                }
                format(node,"D:"+File.separator+"code" +File.separator+ "node" +File.separator+nodeEntry.getKey()+"Node.java","D:"+File.separator+"IdeaProjects"+File.separator+"kapacitor-java"+File.separator+"src"+File.separator+"main"+File.separator+"java"+File.separator+"com"+File.separator+"azier"+File.separator+"generator"+File.separator+"templ"+File.separator+"node.ftl");
            }
            //再生成Node
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static String readFile(File file){
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(file);
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
            BufferedReader reader = new BufferedReader(inputStreamReader);
            String tempString = null;
            StringBuffer json = new StringBuffer();
            while ((tempString = reader.readLine()) != null) {
                json.append(tempString);
            }
            return json.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public static File format(Object dataModel,String saveFilePath,String tempPath) throws Exception{
        File outFile = null;
        try {
            // ========================获取模板========================================
//            InputStream stream =TestScript.class.getClassLoader().getResourceAsStream("person.ftl");  //linux环境下也可用
            InputStream stream = new FileInputStream(new File(tempPath));
            File file = File.createTempFile("temp", "java"); // 创建一个空名为temp的临时文件 temp.html
            //流方式将模板文件写入临时文件
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            // 设置相关配置
            Configuration configuration = new Configuration();
            configuration.setDirectoryForTemplateLoading(new File(file.getParent())); // 临时文件所存在的位置
            configuration.setDefaultEncoding("UTF-8");// 默认编码
            Template t = null;
            try {
                t = configuration.getTemplate(file.getName()); // 文件名
                t.setEncoding("UTF-8");
            } catch (IOException e) {
                e.printStackTrace();
            }
            //===========================生成页面========================================
            outFile = new File(saveFilePath);  //文件生成地址（可自己配置）
            if (!outFile.getParentFile().exists()) {
                outFile.getParentFile().mkdir();
            }
            if(outFile.exists()){
                outFile.delete();
            }
            Writer out = null;
            try {
                out = new BufferedWriter(new OutputStreamWriter(
                        new FileOutputStream(outFile),"UTF-8"));
            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            //数据与模板整合写入文件
            t.process(dataModel, out);
            //关闭流
            out.close();
            stream.close();
            //将临时文件删除
            file.delete();
        } catch (IOException e) {
            e.printStackTrace();
        }  finally {
            return outFile;
        }
    }
}
